package gui;

import java.util.LinkedHashSet;
import java.util.Set;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.PojoObservables;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.observable.set.WritableSet;
import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
import org.eclipse.jface.databinding.viewers.ObservableSetContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

import data.ProjectCharacteristicsProvider;
import data.model.ProjectCharacteristics;

public class ProjectCharacteristicsComposite extends Composite {
	private final ProjectCharacteristicsProvider projectCharacteristicsProvider;

	private final DataBindingContext m_bindingContext;
	private final TableViewer tableViewerProductData;

	/**
	 * Create the composite.
	 * 
	 * @param parent
	 * @param style
	 * @param projectHealthCriteria
	 */
	public ProjectCharacteristicsComposite(Composite parent, int style,
			ProjectCharacteristicsProvider projectCharacteristicsProvider,
			final ProjectCharacteristics projectHealthCriteria) {
		super(parent, style);
		GridLayout gridLayout = new GridLayout(1, false);
		gridLayout.marginWidth = 0;
		gridLayout.marginHeight = 0;
		setLayout(gridLayout);

		this.projectCharacteristicsProvider = projectCharacteristicsProvider;

		tableViewerProductData = new TableViewer(this, SWT.BORDER
				| SWT.FULL_SELECTION);
		Table tableProductData = tableViewerProductData.getTable();
		tableProductData.setHeaderVisible(true);
		GridData gd_tableProductData = new GridData(SWT.FILL, SWT.FILL, true,
				true, 1, 1);
		gd_tableProductData.widthHint = 400;
		tableProductData.setLayoutData(gd_tableProductData);

		TableViewerColumn tableViewerColumnNumberOfTasks = new TableViewerColumn(
				tableViewerProductData, SWT.NONE);
		TableColumn tblclmnNumberOfTasks = tableViewerColumnNumberOfTasks
				.getColumn();
		tblclmnNumberOfTasks.setToolTipText("Number of Tasks");
		tblclmnNumberOfTasks.setWidth(50);
		tblclmnNumberOfTasks.setText("NoT");

		TableViewerColumn tableViewerColumnNumberOfBugs = new TableViewerColumn(
				tableViewerProductData, SWT.NONE);
		TableColumn tblclmnNumberOfBugs = tableViewerColumnNumberOfBugs
				.getColumn();
		tblclmnNumberOfBugs.setToolTipText("Number of Bugs");
		tblclmnNumberOfBugs.setWidth(50);
		tblclmnNumberOfBugs.setText("NoB");

		TableViewerColumn tableViewerColumnLinesOfCode = new TableViewerColumn(
				tableViewerProductData, SWT.NONE);
		TableColumn tblclmnLinesOfCode = tableViewerColumnLinesOfCode
				.getColumn();
		tblclmnLinesOfCode.setToolTipText("Lines of Code");
		tblclmnLinesOfCode.setWidth(50);
		tblclmnLinesOfCode.setText("LoC");

		TableViewerColumn tableViewerColumnNumberOfComponents = new TableViewerColumn(
				tableViewerProductData, SWT.NONE);
		TableColumn tblclmnNumberOfComponents = tableViewerColumnNumberOfComponents
				.getColumn();
		tblclmnNumberOfComponents.setToolTipText("Number of Components");
		tblclmnNumberOfComponents.setWidth(50);
		tblclmnNumberOfComponents.setText("NoC");

		TableViewerColumn tableViewerColumnNumberOfTestCases = new TableViewerColumn(
				tableViewerProductData, SWT.NONE);
		TableColumn tblclmnNumberOfTestCases = tableViewerColumnNumberOfTestCases
				.getColumn();
		tblclmnNumberOfTestCases.setToolTipText("Number of Test Cases");
		tblclmnNumberOfTestCases.setWidth(50);
		tblclmnNumberOfTestCases.setText("NoTC");

		TableViewerColumn tableViewerColumnPercentageOfSuccessfulTests = new TableViewerColumn(
				tableViewerProductData, SWT.NONE);
		TableColumn tblclmnPercentageOfSuccessfulTests = tableViewerColumnPercentageOfSuccessfulTests
				.getColumn();
		tblclmnPercentageOfSuccessfulTests
				.setToolTipText("Percentage of Successful Tests");
		tblclmnPercentageOfSuccessfulTests.setWidth(50);
		tblclmnPercentageOfSuccessfulTests.setText("PoST");

		TableViewerColumn tableViewerColumnPercentageOfCodeCoverage = new TableViewerColumn(
				tableViewerProductData, SWT.NONE);
		TableColumn tblclmnPercentageOfCodeCoverage = tableViewerColumnPercentageOfCodeCoverage
				.getColumn();
		tblclmnPercentageOfCodeCoverage
				.setToolTipText("Percentage of Code Coverage");
		tblclmnPercentageOfCodeCoverage.setWidth(50);
		tblclmnPercentageOfCodeCoverage.setText("PoCC");

		TableViewerColumn tableViewerColumn = new TableViewerColumn(
				tableViewerProductData, SWT.NONE);
		TableColumn tblclmnStatus = tableViewerColumn.getColumn();
		tblclmnStatus.setWidth(49);
		tblclmnStatus.setText("Status");

		if (projectHealthCriteria != null) {
			tableProductData.addListener(SWT.PaintItem, new Listener() {
				@Override
				public void handleEvent(Event event) {
					TableItem item = (TableItem) event.item;
					ProjectCharacteristicsProvider entry = (ProjectCharacteristicsProvider) item
							.getData();

					if (entry.getNumberOfTasks() >= projectHealthCriteria
							.getNumberOfTasks())
						item.setBackground(
								0,
								item.getDisplay().getSystemColor(
										SWT.COLOR_GREEN));
					else
						item.setBackground(
								0,
								item.getDisplay().getSystemColor(
										SWT.COLOR_WHITE));

					if (entry.getNumberOfBugs() <= projectHealthCriteria
							.getNumberOfBugs())
						item.setBackground(
								1,
								item.getDisplay().getSystemColor(
										SWT.COLOR_GREEN));
					else
						item.setBackground(
								1,
								item.getDisplay().getSystemColor(
										SWT.COLOR_WHITE));

					if (entry.getLinesOfCode() >= projectHealthCriteria
							.getLinesOfCode())
						item.setBackground(
								2,
								item.getDisplay().getSystemColor(
										SWT.COLOR_GREEN));
					else
						item.setBackground(
								2,
								item.getDisplay().getSystemColor(
										SWT.COLOR_WHITE));

					if (entry.getNumberOfComponents() >= projectHealthCriteria
							.getNumberOfComponents())
						item.setBackground(
								3,
								item.getDisplay().getSystemColor(
										SWT.COLOR_GREEN));
					else
						item.setBackground(
								3,
								item.getDisplay().getSystemColor(
										SWT.COLOR_WHITE));

					if (entry.getNumberOfTestCases() >= projectHealthCriteria
							.getNumberOfTestCases())
						item.setBackground(
								4,
								item.getDisplay().getSystemColor(
										SWT.COLOR_GREEN));
					else
						item.setBackground(
								4,
								item.getDisplay().getSystemColor(
										SWT.COLOR_WHITE));

					if (entry.getPercentageOfSuccessfulTests() >= projectHealthCriteria
							.getPercentageOfSuccessfulTests())
						item.setBackground(
								5,
								item.getDisplay().getSystemColor(
										SWT.COLOR_GREEN));
					else
						item.setBackground(
								5,
								item.getDisplay().getSystemColor(
										SWT.COLOR_WHITE));

					if (entry.getPercentageOfCodeCoverage() >= projectHealthCriteria
							.getPercentageOfCodeCoverage())
						item.setBackground(
								6,
								item.getDisplay().getSystemColor(
										SWT.COLOR_GREEN));
					else
						item.setBackground(
								6,
								item.getDisplay().getSystemColor(
										SWT.COLOR_WHITE));

					int notHealthCount = 0;

					if (entry.getLinesOfCode() < projectHealthCriteria
							.getLinesOfCode())
						notHealthCount++;

					if (entry.getNumberOfBugs() > projectHealthCriteria
							.getNumberOfBugs())
						notHealthCount++;

					if (entry.getNumberOfComponents() < projectHealthCriteria
							.getNumberOfComponents())
						notHealthCount++;

					if (entry.getNumberOfTasks() < projectHealthCriteria
							.getNumberOfTasks())
						notHealthCount++;

					if (entry.getNumberOfTestCases() < projectHealthCriteria
							.getNumberOfTestCases())
						notHealthCount++;

					if (entry.getPercentageOfCodeCoverage() < projectHealthCriteria
							.getPercentageOfCodeCoverage())
						notHealthCount++;

					if (entry.getPercentageOfSuccessfulTests() < projectHealthCriteria
							.getPercentageOfSuccessfulTests())
						notHealthCount++;

					switch (notHealthCount) {
					case 0:
						item.setBackground(
								7,
								item.getDisplay().getSystemColor(
										SWT.COLOR_GREEN));
						break;

					case 7:
						item.setBackground(7,
								item.getDisplay().getSystemColor(SWT.COLOR_RED));
						break;

					default:
						item.setBackground(
								7,
								item.getDisplay().getSystemColor(
										SWT.COLOR_YELLOW));
						break;
					}

				}
			});
		}

		m_bindingContext = initDataBindings();
	}

	protected DataBindingContext initDataBindings() {
		DataBindingContext bindingContext = new DataBindingContext();
		//
		ObservableSetContentProvider setContentProvider = new ObservableSetContentProvider();
		tableViewerProductData.setContentProvider(setContentProvider);
		//
		IObservableMap[] observeMaps = PojoObservables.observeMaps(
				setContentProvider.getKnownElements(),
				ProjectCharacteristicsProvider.class, new String[] {
						"numberOfTasks", "numberOfBugs", "linesOfCode",
						"numberOfComponents", "numberOfTestCases",
						"percentageOfSuccessfulTests",
						"percentageOfCodeCoverage" });
		tableViewerProductData.setLabelProvider(new ObservableMapLabelProvider(
				observeMaps));
		//
		WritableSet writableSet = new WritableSet(
				getProjectCharacteristicsProvidersAsSet(),
				ProjectCharacteristicsProvider.class);
		tableViewerProductData.setInput(writableSet);
		//
		return bindingContext;
	}

	private Set<ProjectCharacteristicsProvider> getProjectCharacteristicsProvidersAsSet() {
		Set<ProjectCharacteristicsProvider> projectCharacteristicsProviders = new LinkedHashSet<ProjectCharacteristicsProvider>();
		projectCharacteristicsProviders.add(projectCharacteristicsProvider);
		return projectCharacteristicsProviders;
	}

}
